﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SettingsProviderConfiguration.cs" company="DevDigital">
//   DevDigital
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Settings.NET
{
    using Settings.NET.Serializers;

    /// <summary>
    /// Settings provider configuration
    /// </summary>
    public class SettingsProviderConfiguration : ISettingsProviderConfiguration
    {
        /// <summary>
        /// The settings provider factory
        /// </summary>
        private readonly SettingsProviderFactory settingsProviderFactory;

        /// <summary>
        /// The current storage
        /// </summary>
        private ISettingsStorage currentStorage;

        /// <summary>
        /// The current serializer
        /// </summary>
        private ISettingsSerializer currentSerializer;

        /// <summary>
        /// The current cache
        /// </summary>
        private ISettingsCache currentCache;

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsProviderConfiguration" /> class.
        /// </summary>
        /// <param name="settingsProviderFactory">The settings provider factory.</param>
        internal SettingsProviderConfiguration(SettingsProviderFactory settingsProviderFactory)
        {
            this.settingsProviderFactory = settingsProviderFactory;
            this.currentSerializer = this.settingsProviderFactory.GetSerializer<SettingsDefaultSerializer>();
        }

        /// <summary>
        /// Sets the default storage to use for any settings provider created with this factory
        /// </summary>
        /// <typeparam name="TStorage">The type of the storage.</typeparam>
        /// <returns>The settings provider configuration</returns>
        public ISettingsProviderConfiguration WithDefaultStorage<TStorage>() where TStorage : ISettingsStorage, new()
        {
            this.currentStorage = this.settingsProviderFactory.GetStorage<TStorage>();
            return this;
        }

        /// <summary>
        /// Sets the default storage to use for any settings provider created with this factory
        /// </summary>
        /// <param name="storage">The storage.</param>
        /// <returns>
        /// The settings provider configuration
        /// </returns>
        public ISettingsProviderConfiguration WithDefaultStorage(ISettingsStorage storage)
        {
            this.currentStorage = storage;
            return this;
        }

        /// <summary>
        /// Sets the default serializer to use for any settings provider created from this factory.
        /// </summary>
        /// <typeparam name="TSerializer">The type of the serializer.</typeparam>
        /// <returns>
        /// The settings provider configuration
        /// </returns>
        public ISettingsProviderConfiguration WithDefaultSerializer<TSerializer>() where TSerializer : ISettingsSerializer, new()
        {
            this.currentSerializer = this.settingsProviderFactory.GetSerializer<TSerializer>();
            return this;
        }

        /// <summary>
        /// Sets the default serializer to use for any settings provider created from this factory.
        /// </summary>
        /// <param name="serializer">The serializer.</param>
        /// <returns>
        /// The settings provider configuration
        /// </returns>
        public ISettingsProviderConfiguration WithDefaultSerializer(ISettingsSerializer serializer)
        {
            this.currentSerializer = serializer;
            return this;
        }

        /// <summary>
        /// Sets the default caching to use for any settings provider created from this factory.
        /// </summary>
        /// <typeparam name="TCache">The type of the cache.</typeparam>
        /// <returns>
        /// The settings provider configuration
        /// </returns>
        public ISettingsProviderConfiguration WithDefaultCache<TCache>() where TCache : ISettingsCache, new()
        {
            this.currentCache = this.settingsProviderFactory.GetCache<TCache>();
            return this;
        }

        /// <summary>
        /// Sets the default caching to use for any settings provider
        /// </summary>
        /// <param name="cache">The cache.</param>
        /// <returns>
        /// The settings provider configuration
        /// </returns>
        public ISettingsProviderConfiguration WithDefaultCache(ISettingsCache cache)
        {
            this.currentCache = cache;
            return this;
        }

        /// <summary>
        /// Gets an instance of the settings provider using the current default configuration
        /// </summary>
        /// <returns>
        /// The settings provider instance
        /// </returns>
        public ISettingsProvider Get()
        {
            var settingsProvider = new SettingsProvider(
                this.settingsProviderFactory,
                this.currentStorage, 
                this.currentSerializer, 
                this.currentCache);

            return settingsProvider;
        }
    }
}